package com.hc.common.datasource.aspect;

import com.hc.common.core.exception.DataSourceNotExistException;
import com.hc.common.core.utils.StringUtils;
import com.hc.common.datasource.DynamicSaasDataSource;
import com.hc.common.security.service.TokenService;
import com.hc.system.api.model.LoginUser;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.CodeSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class  datasourceAspect {
    public static final String DATASOURCENAME_PARM = "datasourceName";
    public static final String TOPIC_SPLIT = "/";
    @Autowired
    private TokenService tokenService;
    @Autowired
    private DynamicSaasDataSource dataSource;

    private Logger log = LoggerFactory.getLogger(datasourceAspect.class);

    @Around("execution(public * com.hc.tenant.controller.*.*(..))" )
    public Object httpRequestAround(ProceedingJoinPoint point) throws Throwable {
        Map<String, Object> parm = parseParm(point);
        String dataSourceName = (String) parm.get(DATASOURCENAME_PARM);
        if( tokenService.getLoginUser()!= null) {
            dataSourceName = tokenService.getLoginUser().getDataSourceName();
        }
        if(StringUtils.isEmpty(dataSourceName) || !dataSource.existDataSource(dataSourceName)) {
            throw new DataSourceNotExistException();
        }

        Object result = getResult(point, dataSourceName);
        return result;

    }

    @Around("execution(public * com.hc.*.config.MqttConfig.MqttDefaultCallBack.messageArrived(..))")
    public Object mqttRequestAround(ProceedingJoinPoint point) throws Throwable {
        String dataSourName = getDataSourNameFromTopic((String)point.getArgs()[0]);
        Object result = getResult(point, dataSourName);
        return result;
    }

    private Map<String, Object> parseParm(ProceedingJoinPoint joinPoint) {
        Map<String, Object> param = new HashMap<>();
        Object[] paramValues = joinPoint.getArgs();
        String[] paramNames = ((CodeSignature)joinPoint.getSignature()).getParameterNames();
        for (int i = 0; i < paramNames.length; i++) {
            param.put(paramNames[i], paramValues[i]);
        }
        return param;
    }

    private String getDataSourNameFromTopic(String topicName){
       String[] arr = topicName.split(TOPIC_SPLIT);
       String token = arr[arr.length-1];
        LoginUser loginUser = tokenService.getLoginUser(token);
        if(loginUser ==null){
            log.error("错误信息:{}",token+" 已过期");
            return null;
        }
        String dataSourceName = loginUser.getDataSourceName();
        return dataSourceName;
    }

    private Object getResult(ProceedingJoinPoint point, String dataSourceName) throws Throwable {
        DynamicSaasDataSource.setDataSource(dataSourceName);
        Object result = point.proceed();
        DynamicSaasDataSource.clearDataSource();
        return result;
    }


//    private Object getResult(ProceedingJoinPoint point, String dataSourceName) throws Throwable {
//        List<Object> list = new ArrayList<Object>();
//        for(Object name : dataSource.getAllDatasource().keySet()) {
//            DynamicSaasDataSource.setDataSource((String) name);
//            TableDataInfo result = (TableDataInfo)point.proceed();
//            DynamicSaasDataSource.clearDataSource();
//            list.add(result);
//        }
//        return list;
//    }
}
